package com.starsoft.trade.trader;

import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.starsoft.frame.util.DateUtil;
import com.starsoft.trade.bean.TradeAcount;
import com.starsoft.trade.bean.TradeAcountStatus;
import com.starsoft.trade.bean.TradeBill;
import com.starsoft.trade.bean.TradePosition;
import com.starsoft.trade.bean.TradeSummary;
import com.starsoft.trade.order.Order;
import com.starsoft.trade.service.AcountStatusService;
import com.starsoft.trade.service.TradeBillService;

@Component
public class TraderService {

	private static Logger logger = LoggerFactory.getLogger(TraderService.class);
	
	@Autowired
	TraderFatory traderFatory;

	@Autowired
	TradeBillService billService;

	@Autowired
	AcountStatusService statusService;

	public List<TradeBill> importBill(TradeAcount acount, InputStream is) {
		Trader trader = traderFatory.getTrader(acount);
		List<TradeBill> bills = trader.getHistory(is);
		Date actStartDate = new Date();
		for (TradeBill bill : bills) {
			if (bill.getBillTime().before(actStartDate))
				actStartDate = bill.getBillTime();
		}
		statusService.deleteStatusAfter(acount.getAcountId(), actStartDate);
		for (TradeBill bill : bills) {
			billService.saveOrUpdate(bill, false);
		}
		return bills;
	}
	
	public TradeAcountStatus getPortfoil(TradeAcount acount) {
		Trader trader = traderFatory.getTrader(acount);
		return trader.getPortflio();
	}

	@Transactional
	public List<TradeBill> synchBill(TradeAcount acount, Date startDate){
		Date initDate = DateUtil.getNext(acount.getInitDate());
		if(startDate==null || startDate.before(initDate)){
			startDate = initDate;
		}
		Trader trader = traderFatory.getTrader(acount);
		List<TradeBill> bills = trader.getHistory(startDate);
		Date actStartDate = new Date();
		for (TradeBill bill : bills) {
			if (bill.getBillTime().before(actStartDate))
				actStartDate = bill.getBillTime();
		}
		billService.deleteBillsAfter(acount.getAcountId(), actStartDate);
		statusService.deleteStatusAfter(acount.getAcountId(), actStartDate);
		for (TradeBill bill : bills) {
			billService.saveOrUpdate(bill);
		}
		return bills;
	}
	
	public String checkPortfoil(TradeAcountStatus status){
		TradeAcount acount = status.getTradeAcount();
		TradeAcountStatus statusEx = getPortfoil(acount);
		
		TradeSummary summary = status.getSummary();
		TradeSummary summaryEx = statusEx.getSummary();
		double cashDiff = summary.getCash()-summaryEx.getCash();
		if(Math.abs(cashDiff/summary.getNetAssert())>0.001){
			return "现金不相等";
		}

		Map<String, Double> positions = new HashMap<String, Double>();
		Map<String, Double> positionsEx = new HashMap<String, Double>();
		for(TradePosition pos : status.getPositions()){
			positions.put(pos.getId().getSecId(), new Double(pos.getSecNum()));
		}
		for(TradePosition pos : statusEx.getPositions()){
			positionsEx.put(pos.getId().getSecId(), new Double(pos.getSecNum()));
		}
		for(Map.Entry<String, Double> entry : positions.entrySet()){
			String secId = entry.getKey();
			Double secNumEx = positionsEx.get(secId);
			if(secNumEx==null || Math.abs(secNumEx-entry.getValue())>0.01){
				return "持仓不一样";
			}
			positionsEx.remove(secId);
		}
		if(!positionsEx.isEmpty()){
			return "持仓不一样";
		}
		return null;
	}
	
	public List<TradeBill> trade(TradeAcount acount, List<Order> orders, TradeAcountStatus status){
		String checkResult = checkPortfoil(status);
		if(checkResult!=null){
			throw new RuntimeException("检查失败不能交易:"+checkResult);
		}
		List<TradeBill> entrust = getEntrust(acount);
		if(entrust!=null && !entrust.isEmpty()){
			throw new RuntimeException("存在委托未成交");
		}
		
		Trader trader = traderFatory.getTrader(acount);
		trader.trade(orders);
		
		int i=0;
		for(;i<10;i++){
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				logger.error(e.getMessage(), e);
			}
			List<TradeBill> bills = getEntrust(acount);
			if(bills==null || bills.isEmpty()){
				logger.info("委托成交");
				break;
			}
		}
		if(i>=10){
			logger.info("委托未成交");
		}
		return null;
	}

	public List<TradeBill> getEntrust(TradeAcount acount){
		Trader trader = traderFatory.getTrader(acount);
		return trader.getEntrust();
	}

}
